namespace SpaceMutinyNameGenerator
{
	using System;
	using System.Collections.Generic;

	public sealed class Names
	{
		private readonly NameList _alreadyGenerated;
		private readonly NameList _firstNames;
		private readonly NameList _lastNamePrefixes;
		private readonly NameList _lastNameSuffixes;
		private readonly NameList _middleNames;
		private readonly NameConfigReader _reader;
		private readonly NameList _usedNames;
		private Int32 _iter;

		public Names()
		{
			_usedNames = new NameList();
			_alreadyGenerated = new NameList();
			_reader = new NameConfigReader();
			_firstNames = _reader.GetFirstNames();
			_middleNames = _reader.GetMiddleNames();
			_lastNamePrefixes = _reader.GetLastNamePrefixes();
			_lastNameSuffixes = _reader.GetLastNameSuffixes();
		}

		public NameList SelectedNames
		{
			get { return _usedNames; }
		}

		public IList<String> AllNames
		{
			get { return _alreadyGenerated.AsList(); }
		}

		public Int32 MaxNumberOfNames
		{
			get { return _alreadyGenerated.Count; }
		}

		public void GetUnusedName()
		{
			String name = _alreadyGenerated[_iter];
			_iter++;
			_usedNames.Add(name);
		}

		internal void Clear()
		{
			_alreadyGenerated.Clear();
			_usedNames.Clear();
		}

		public void GenerateAllNames()
		{
			Clear();

			RandomizeNameLists();

			// names using a middle modifier            
			_firstNames.ForEach(first =>
			                    _middleNames.ForEach(middle =>
			                                         _lastNamePrefixes.ForEach(lastA => AddNameToGeneratedList(first, middle, lastA))));

			// names w/o a middle modifier   
			_firstNames.ForEach(first =>
			                    _lastNamePrefixes.ForEach(lastA =>
			                                              _lastNameSuffixes.ForEach(lastB => AddNameToGeneratedList(first, lastA, lastB))));

			_alreadyGenerated.Randomize();
		}

		private void RandomizeNameLists()
		{
			_firstNames.Randomize();
			_middleNames.Randomize();
			_lastNamePrefixes.Randomize();
			_lastNameSuffixes.Randomize();
		}

		private void AddNameToGeneratedList(String nameA, String nameB, String nameC)
		{
			_alreadyGenerated.Add(nameA + " " + nameB + nameC);
		}
	}
}